/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package lol.clann.bukkit.pluginboot.util;

import lol.clann.bukkit.pluginboot.task.BukkitTimer;
import lol.clann.clannboot.annotation.svc.Service;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandException;
import org.bukkit.command.CommandSender;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Supplier;

/**
 * 提供一个接口,让异步线程的指令在主线程里执行
 *
 * @author zyp
 */
//自动初始化
@Service
public class CommandUtils {

    /**
     * 缓冲指令
     */
    private LinkedBlockingQueue<command> buffer = new LinkedBlockingQueue();

    @BukkitTimer(async = false, dely = "1", interval = "1")
    private void task() {
        while (!buffer.isEmpty()) {
            command c = buffer.poll();
            if (c == null) {
                break;
            }
            Bukkit.dispatchCommand(c.sender, c.getCommand());
        }
    }

    /**
     * 以控制台身份运行指令
     *
     * @param command
     */
    public void runConsoleCommand(String command) {
        runCommand(Bukkit.getConsoleSender(), command);
    }

    /**
     * 以给定身份运行指令
     *
     * @param sender
     * @param command
     */
    public void runCommand(CommandSender sender, String command) {
        buffer.add(new command(sender, command));
    }

    public Supplier<CommandException> commandExceptionSupplier(String message) {
        return () -> new CommandException(message);
    }

    public String toCommand(String s) {
        return s.startsWith("/") ? s : "/" + s;
    }

    private static class command {

        CommandSender sender;
        private String command;

        public command(CommandSender sender, String command) {
            this.command = command;
            this.sender = sender;
        }

        public String getCommand() {
            if (command.startsWith("/")) {
                return command.substring(1);
            } else {
                return command;
            }
        }
    }
}
